#include "utils_init.h"
#include "utils_time.h"
#include "utils_log.h"
#include "utils_stack_trace.h"
#include "utils_mem.h"

#include <string>

namespace El {
namespace Utils {

namespace {

// 打印启动横幅
void PrintStartupBanner()
{
    const std::string banner = R"(
 
  ███████╗███╗   ██╗██████╗ ██╗     ███████╗███████╗███████╗
  ██╔════╝████╗  ██║██╔══██╗██║     ██╔════╝██╔════╝██╔════╝
  █████╗  ██╔██╗ ██║██║  ██║██║     █████╗  ███████╗███████╗
  ██╔══╝  ██║╚██╗██║██║  ██║██║     ██╔══╝  ╚════██║╚════██║
  ███████╗██║ ╚████║██████╔╝███████╗███████╗███████║███████║
  ╚══════╝╚═╝  ╚═══╝╚═════╝ ╚══════╝╚══════╝╚══════╝╚══════╝
)";

    EL_INFO(banner);
}

} // namespace

bool base_init(nlohmann::json &config)
{
    // 初始化日志
    std::string logFilePath = "/mnt/log/app.log";
    int32_t maxLogFileSize = 1024 * 1024;
    int32_t maxLogFiles = 3;
    std::string logLevel = "info";
    bool enableLogToFile = false;
    if (config.contains("log")) {
        logFilePath = config["log"].value("filePath", logFilePath);
        enableLogToFile = config["log"].value("enableToFile", enableLogToFile);
        maxLogFiles = config["log"].value("maxFiles", maxLogFiles);
        maxLogFileSize = config["log"].value("maxFileSize", maxLogFileSize);
        logLevel = config["log"].value("level", logLevel);
    }
    Log::GetInstance().init(logFilePath, "default", maxLogFileSize, maxLogFiles);
    Log::GetInstance().enableFileLogging(enableLogToFile);
    Log::GetInstance().setLogLevel(logLevel);

    // 打印启动横幅，确保内存池信息输出在其后
    PrintStartupBanner();

    // 初始化内存管理
    if (config.contains("mem")) {
        size_t totalSize = config["mem"].value("totalSize", 3 * 1024 * 1024);
        size_t chunkSize = config["mem"].value("chunkSize", 1024);
        size_t alignSize = config["mem"].value("alignSize", 4);
        Buddy::MemoryOperator memop = {malloc, free, memcpy};
        Buddy::PoolParameter param = {totalSize, chunkSize, alignSize};
        Buddy::GetInstance().Configure(Buddy::Policy::kPool, &memop, &param);
    }

    // 初始化堆栈跟踪
    StackTrace::GetInstance().Start();

    return true;
}

} // namespace Utils
} // namespace El
